/*
 * Copyright 2012 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.icebergteam.warfacewidget.ui;

import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.json.JSONObject;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import android.annotation.TargetApi;
import android.app.ActionBar;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.MenuItem;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import com.google.android.youtube.player.YouTubePlayer;
import com.google.android.youtube.player.YouTubePlayerFragment;
import com.icebergteam.warfacewidget.AppManager;
import com.icebergteam.warfacewidget.R;
import com.icebergteam.warfacewidget.core.IntentService;
import com.icebergteam.warfacewidget.core.LogManager;
import com.icebergteam.warfacewidget.core.connection.NetworkManager;

/**
 * A sample showing how to use the ActionBar as an overlay when the video is playing in fullscreen.
 *
 * The ActionBar is the only view allowed to overlay the player, so it is a useful place to put
 * custom application controls when the video is in fullscreen. The ActionBar can not change back
 * and forth between normal mode and overlay mode, so to make sure our application's content
 * is not covered by the ActionBar we want to pad our root view when we are not in fullscreen.
 */
@TargetApi(11)
public class YouTubeVideoPlayerActivity extends YouTubeFailureRecoveryActivity  implements
    YouTubePlayer.OnFullscreenListener {

  private ActionBarPaddedFrameLayout viewContainer;
  private YouTubePlayerFragment playerFragment;
  
  public static final String className = YouTubeVideoPlayerActivity.class.getCanonicalName();
  public static String KEY_INTENT_ID = String.format("%s.KEY_ID",
			className);
  public static final String MASK_JSON_FEED = "http://gdata.youtube.com/feeds/api/videos/%s?v=2&alt=jsonc";
  public static final String PATTERN_URL = "(?:youtu\\.be\\/|youtube\\.com)";
  public static final String PATTERN_ID = "([\\w\\-]{10,12})";
  
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_youtube_player);

    viewContainer = (ActionBarPaddedFrameLayout) findViewById(R.id.view_container);
    playerFragment =
        (YouTubePlayerFragment) getFragmentManager().findFragmentById(R.id.player_fragment);
    
    playerFragment.initialize(DeveloperKey.DEVELOPER_KEY, this);
    viewContainer.setActionBar(getActionBar());

    // Action bar background is transparent by default.
    getActionBar().setDisplayHomeAsUpEnabled(true);
  
    getActionBar().setBackgroundDrawable(new ColorDrawable(0xAA000000));
    
  }
  
  @Override
  public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer player,
      boolean wasRestored) {
	  
	  try{
		  player.addFullscreenControlFlag(YouTubePlayer.FULLSCREEN_FLAG_CUSTOM_LAYOUT);
		    player.setOnFullscreenListener(this);

		    if (!wasRestored) {
		    
		    	String id = getIntent().getStringExtra(YouTubeVideoPlayerActivity.KEY_INTENT_ID);
		    	player.loadVideo((id ==null)?"invalid": id);
		      
		    }
	  }
	  catch(Exception e){
		  LogManager.LogE(className, LogManager.getExecuteMethodName(), e.getLocalizedMessage());
		  e.printStackTrace();
	  }
   
   
  }

  @Override
  protected YouTubePlayer.Provider getYouTubePlayerProvider() {
    return (YouTubePlayerFragment) getFragmentManager().findFragmentById(R.id.player_fragment);
  }

  @Override
  public void onFullscreen(boolean fullscreen) {
    viewContainer.setEnablePadding(!fullscreen);

    ViewGroup.LayoutParams playerParams = playerFragment.getView().getLayoutParams();
    if (fullscreen) {
    
      playerParams.width = MATCH_PARENT;
      playerParams.height = MATCH_PARENT;
    } else {
     
      playerParams.width = 0;
      playerParams.height = WRAP_CONTENT;
    }
  }

  /**
   * This is a FrameLayout which adds top-padding equal to the height of the ActionBar unless
   * disabled by {@link #setEnablePadding(boolean)}.
   */
  public static final class ActionBarPaddedFrameLayout extends FrameLayout {

    private ActionBar actionBar;
    private boolean paddingEnabled;

    public ActionBarPaddedFrameLayout(Context context) {
      this(context, null);
    }

    public ActionBarPaddedFrameLayout(Context context, AttributeSet attrs) {
      this(context, attrs, 0);
    }

    public ActionBarPaddedFrameLayout(Context context, AttributeSet attrs, int defStyle) {
      super(context, attrs, defStyle);
      paddingEnabled = true;
    }

    public void setActionBar(ActionBar actionBar) {
      this.actionBar = actionBar;
      requestLayout();
    }

    public void setEnablePadding(boolean enable) {
      paddingEnabled = enable;
      requestLayout();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
      int topPadding =
          paddingEnabled && actionBar != null && actionBar.isShowing() ? actionBar.getHeight() : 0;
      setPadding(0, topPadding, 0, 0);

      super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
  

  }

	@Override
	public boolean onMenuItemSelected(int featureId, MenuItem item) {
		if(item.getItemId() == android.R.id.home){
			finish();
		}
		return super.onMenuItemSelected(featureId, item);
	}
	
	
	public static boolean initByUrl(String url, Context ctx){
		
		try{
			String youtubeId = YouTubeVideoPlayerActivity.getYoutubeID(url, true);
	    	 LogManager.LogVA(className, youtubeId); 	
	    	if(youtubeId != null){
	    		return YouTubeVideoPlayerActivity.initById(youtubeId, ctx);
	    	}
	    	return false;
		}
		catch(Exception e){
			LogManager.LogE(className, LogManager.getExecuteMethodName(),e.getLocalizedMessage());
			e.printStackTrace();
			return false;
		}
	}
	
	public static boolean initById(String id, Context ctx){
		try{	
			Intent localIntent = new Intent();
    		localIntent.setClass(ctx, YouTubeVideoPlayerActivity.class);
    		localIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
			localIntent.putExtra(YouTubeVideoPlayerActivity.KEY_INTENT_ID, id);
			ctx.startActivity(localIntent);
			return true;
		}
		catch(Exception e){
			LogManager.LogE(className, LogManager.getExecuteMethodName(),e.getLocalizedMessage());
			e.printStackTrace();
			return false;
		}
	}
	
	public static String getYoutubeVideoThumbnailById(String youtubeId){
		try {
			JSONObject jsonObject = YouTubeVideoPlayerActivity.getYoutubeVideoInfo(youtubeId);
			return jsonObject.getJSONObject("data").getJSONObject("thumbnail").getString("hqDefault");
		} catch (Exception e) {
			LogManager.LogEA(className, youtubeId, "bug", e.getLocalizedMessage());
			return null;
		}
	}
	
	public static String getYoutubeVideoThumbnailByUrl(String youtubeUrl){
		try {
			String youtubeId = YouTubeVideoPlayerActivity.getYoutubeID(youtubeUrl, false);
			return  getYoutubeVideoThumbnailById(youtubeId);
		} catch (Exception e) {
			LogManager.LogEA(className, youtubeUrl, "bug", e.getLocalizedMessage());
			return null;
		}
	}
	
	public static JSONObject getYoutubeVideoInfo(String youtubeId){
		try {
			return NetworkManager.getJSON(String.format(MASK_JSON_FEED, youtubeId ));
		} catch (Exception e) {
			LogManager.LogEA(className, youtubeId, "bug", String.format(MASK_JSON_FEED, youtubeId ), e.getLocalizedMessage());
			return null;
		}
	}
	
	public static String getYoutubeID(String url, boolean checkID){
		try{
			Pattern checkYoutubeLink = Pattern.compile(PATTERN_URL);
			if(	checkYoutubeLink.matcher(url).find()){
				Pattern patternYoutubeLink = Pattern.compile(PATTERN_ID);
				Matcher matcher =  patternYoutubeLink.matcher(url);
				matcher.find(); 
				String youtubeId = matcher.group();
				LogManager.LogVA(className, url, youtubeId);
				if(checkID && YouTubeVideoPlayerActivity.getYoutubeVideoInfo(youtubeId)!= null)
					return youtubeId;   
				else if(checkID){
					return null;
				}
				
				return youtubeId;
			}
			return null;
		}
		catch(Exception e){
			LogManager.LogE(className, LogManager.getExecuteMethodName(), url, e.getLocalizedMessage());
			return null;
		}
		
	}
	
	public static String getYoutubeID(Element object, boolean checkID){
		String urlVideo = null;
		
		if((urlVideo = getYoutubeUrlObjectAttr(object, false))!= null ){
			return YouTubeVideoPlayerActivity.getYoutubeID(urlVideo,checkID);
		}
		else if((urlVideo = getYoutubeUrlObjectParam(object, false))!= null){
			return YouTubeVideoPlayerActivity.getYoutubeID(urlVideo,checkID);
		}
		else if((urlVideo = getYoutubeUrlIframeAttr(object, false))!= null){
			return YouTubeVideoPlayerActivity.getYoutubeID(urlVideo,checkID);
		}
		
		return null;
	}
	
	public static String getYoutubeUrl(Element object, boolean checkID){
		String url ;
		
		if((url = getYoutubeUrlIframeAttr(object, checkID))!= null){
			return (url);
		}
		else if((url = getYoutubeUrlObjectAttr(object, checkID))!= null){
			return (url);
		}
		else if((url = getYoutubeUrlObjectParam(object,checkID))!= null){
			return (url);
		}
		
		return null;
	}
	

	private static String getYoutubeUrlObjectAttr(Element object, boolean checkID){
		String urlVideo = object.attr("data");
		LogManager.LogVA(className, urlVideo);
		if(checkID && getYoutubeID(urlVideo, checkID)!= null){
			return urlVideo;
		}
		else if(checkID){
			return null;
		}
		return (urlVideo.isEmpty()) ? null: urlVideo;
	}
	private static String getYoutubeUrlObjectParam(Element object, boolean checkID){
		Elements paramsData = object.select("[name = movie]");
		String urlVideo = (paramsData.first()== null)?null:(paramsData.first().attr("value"));
		LogManager.LogVA(className, urlVideo);
		if(checkID && getYoutubeID(urlVideo, checkID)!= null){
			return urlVideo;
		}
		else if(checkID){
			return null;
		}
		return (urlVideo == null) ? null: urlVideo;	
	}
	private static String getYoutubeUrlIframeAttr(Element object, boolean checkID){
		String urlVideo = object.attr("src");
		LogManager.LogVA(className, urlVideo);
		if(checkID && getYoutubeID(urlVideo, checkID)!= null){
			return urlVideo;
		}
		else if(checkID){
			return null;
		}
		return (urlVideo.isEmpty()) ? null: urlVideo;
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		Intent intent = (Intent) getIntent().clone();
		LogManager.LogVA(className, intent);
		if(intent.getStringExtra(IntentService.KEY_INTENTSERVICE) != null && intent.getStringExtra(IntentService.KEY_INTENTSERVICE).equals(IntentService.UPDATE_VIDEOS_READ )){
				intent.setClass(AppManager.getContext(), IntentService.class);
				startService(intent);
		}
		
	}
	
	
}
